From fa80bb23249c2fb6da2a1a16c84a1c884cab1494 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 15 May 2014 22:36:48 -0400 Subject: [PATCH] inspector: Improve actions tab React to action group changes, and allow changing action states. --- gtk/inspector/actions.c | 198 +++++++++++++++++++++++++++++++++------ gtk/inspector/actions.ui | 4 +- 2 files changed, 172 insertions(+), 30 deletions(-) diff --git a/gtk/inspector/actions.c b/gtk/inspector/actions.c index 2adca38e62..ab835945af 100644 --- a/gtk/inspector/actions.c +++ b/gtk/inspector/actions.c @@ -26,13 +26,16 @@ enum COLUMN_NAME, COLUMN_ENABLED, COLUMN_PARAMETER, - COLUMN_STATE + COLUMN_STATE, + COLUMN_GROUP }; struct _GtkInspectorActionsPrivate { GtkListStore *model; GtkWidget *prefix_label; + GHashTable *groups; + GHashTable *iters; }; G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorActions, gtk_inspector_actions, GTK_TYPE_BOX) @@ -41,58 +44,167 @@ static void gtk_inspector_actions_init (GtkInspectorActions *sl) { sl->priv = gtk_inspector_actions_get_instance_private (sl); + sl->priv->iters = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) gtk_tree_iter_free); + sl->priv->groups = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + g_free); gtk_widget_init_template (GTK_WIDGET (sl)); } static void -add_actions (GtkInspectorActions *sl, - const gchar *prefix, - GActionGroup *group) +add_action (GtkInspectorActions *sl, + GActionGroup *group, + const gchar *prefix, + const gchar *name) { GtkTreeIter iter; - gint i; - gchar **names; gboolean enabled; const gchar *parameter; GVariant *state; gchar *state_string; + enabled = g_action_group_get_action_enabled (group, name); + parameter = (const gchar *)g_action_group_get_action_parameter_type (group, name); + state = g_action_group_get_action_state (group, name); + if (state) + state_string = g_variant_print (state, FALSE); + else + state_string = g_strdup (""); + gtk_list_store_append (sl->priv->model, &iter); + gtk_list_store_set (sl->priv->model, &iter, + COLUMN_PREFIX, prefix, + COLUMN_NAME, name, + COLUMN_ENABLED, enabled, + COLUMN_PARAMETER, parameter, + COLUMN_STATE, state_string, + COLUMN_GROUP, group, + -1); + g_hash_table_insert (sl->priv->iters, + g_strconcat (prefix, ".", name, NULL), + gtk_tree_iter_copy (&iter)); + g_free (state_string); +} + +static void +action_added_cb (GActionGroup *group, + const gchar *action_name, + GtkInspectorActions *sl) +{ + const gchar *prefix; + prefix = g_hash_table_lookup (sl->priv->groups, group); + add_action (sl, group, prefix, action_name); +} + +static void +action_removed_cb (GActionGroup *group, + const gchar *action_name, + GtkInspectorActions *sl) +{ + const gchar *prefix; + gchar *key; + GtkTreeIter *iter; + prefix = g_hash_table_lookup (sl->priv->groups, group); + key = g_strconcat (prefix, ".", action_name, NULL); + iter = g_hash_table_lookup (sl->priv->iters, key); + gtk_list_store_remove (sl->priv->model, iter); + g_hash_table_remove (sl->priv->iters, key); + g_free (key); +} + +static void +action_enabled_changed_cb (GActionGroup *group, + const gchar *action_name, + gboolean enabled, + GtkInspectorActions *sl) +{ + const gchar *prefix; + gchar *key; + GtkTreeIter *iter; + prefix = g_hash_table_lookup (sl->priv->groups, group); + key = g_strconcat (prefix, ".", action_name, NULL); + iter = g_hash_table_lookup (sl->priv->iters, key); + gtk_list_store_set (sl->priv->model, iter, + COLUMN_ENABLED, enabled, + -1); + g_free (key); +} + +static void +action_state_changed_cb (GActionGroup *group, + const gchar *action_name, + GVariant *state, + GtkInspectorActions *sl) +{ + const gchar *prefix; + gchar *key; + GtkTreeIter *iter; + gchar *state_string; + prefix = g_hash_table_lookup (sl->priv->groups, group); + key = g_strconcat (prefix, ".", action_name, NULL); + iter = g_hash_table_lookup (sl->priv->iters, key); + if (state) + state_string = g_variant_print (state, FALSE); + else + state_string = g_strdup (""); + gtk_list_store_set (sl->priv->model, iter, + COLUMN_STATE, state_string, + -1); + g_free (state_string); + g_free (key); +} + +static void +add_group (GtkInspectorActions *sl, + GActionGroup *group, + const gchar *prefix) +{ + gint i; + gchar **names; + gtk_widget_show (GTK_WIDGET (sl)); + g_signal_connect (group, "action-added", G_CALLBACK (action_added_cb), sl); + g_signal_connect (group, "action-removed", G_CALLBACK (action_removed_cb), sl); + g_signal_connect (group, "action-enabled-changed", G_CALLBACK (action_enabled_changed_cb), sl); + g_signal_connect (group, "action-state-changed", G_CALLBACK (action_state_changed_cb), sl); + g_hash_table_insert (sl->priv->groups, group, g_strdup (prefix)); + names = g_action_group_list_actions (group); for (i = 0; names[i]; i++) - { - enabled = g_action_group_get_action_enabled (group, names[i]); - parameter = (const gchar *)g_action_group_get_action_parameter_type (group, names[i]); - state = g_action_group_get_action_state (group, names[i]); - if (state) - state_string = g_variant_print (state, FALSE); - else - state_string = g_strdup (""); - gtk_list_store_append (sl->priv->model, &iter); - gtk_list_store_set (sl->priv->model, &iter, - COLUMN_PREFIX, prefix, - COLUMN_NAME, names[i], - COLUMN_ENABLED, enabled, - COLUMN_PARAMETER, parameter, - COLUMN_STATE, state_string, - -1); - g_free (state_string); - } + add_action (sl, group, prefix, names[i]); g_strfreev (names); } +static void +disconnect_group (gpointer key, gpointer value, gpointer data) +{ + GActionGroup *group = key; + GtkInspectorActions *sl = data; + + g_signal_handlers_disconnect_by_func (group, action_added_cb, sl); + g_signal_handlers_disconnect_by_func (group, action_removed_cb, sl); + g_signal_handlers_disconnect_by_func (group, action_enabled_changed_cb, sl); + g_signal_handlers_disconnect_by_func (group, action_state_changed_cb, sl); +} + void gtk_inspector_actions_set_object (GtkInspectorActions *sl, GObject *object) { - gtk_list_store_clear (sl->priv->model); gtk_widget_hide (GTK_WIDGET (sl)); - + g_hash_table_foreach (sl->priv->groups, disconnect_group, sl); + g_hash_table_remove_all (sl->priv->groups); + g_hash_table_remove_all (sl->priv->iters); + gtk_list_store_clear (sl->priv->model); + if (GTK_IS_APPLICATION (object)) - add_actions (sl, "app", G_ACTION_GROUP (object)); + add_group (sl, G_ACTION_GROUP (object), "app"); else if (GTK_IS_APPLICATION_WINDOW (object)) - add_actions (sl, "win", G_ACTION_GROUP (object)); + add_group (sl, G_ACTION_GROUP (object), "win"); else if (GTK_IS_WIDGET (object)) { gchar **prefixes; @@ -105,13 +217,40 @@ gtk_inspector_actions_set_object (GtkInspectorActions *sl, for (i = 0; prefixes[i]; i++) { group = _gtk_widget_get_action_group (GTK_WIDGET (object), prefixes[i]); - add_actions (sl, prefixes[i], group); + add_group (sl, group, prefixes[i]); } g_free (prefixes); } } } +static void +state_edited (GtkCellRenderer *cell, + const gchar *path_string, + const gchar *new_text, + GtkInspectorActions *sl) +{ + GtkTreePath *path; + GtkTreeIter iter; + GActionGroup *group; + gchar *name; + GError *error = NULL; + GVariant *state; + + path = gtk_tree_path_new_from_string (path_string); + gtk_tree_model_get_iter (GTK_TREE_MODEL (sl->priv->model), &iter, path); + gtk_tree_path_free (path); + + gtk_tree_model_get (GTK_TREE_MODEL (sl->priv->model), &iter, + COLUMN_GROUP, &group, + COLUMN_NAME, &name, + -1); + state = g_variant_parse (NULL, new_text, NULL, NULL, &error); + if (state) + g_action_group_change_action_state (group, name, state); + g_free (name); +} + static void gtk_inspector_actions_class_init (GtkInspectorActionsClass *klass) { @@ -120,6 +259,7 @@ gtk_inspector_actions_class_init (GtkInspectorActionsClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/inspector/actions.ui"); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, model); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, prefix_label); + gtk_widget_class_bind_template_callback (widget_class, state_edited); } // vim: set et sw=2 ts=2: diff --git a/gtk/inspector/actions.ui b/gtk/inspector/actions.ui index cdc92b9413..37776f0037 100644 --- a/gtk/inspector/actions.ui +++ b/gtk/inspector/actions.ui @@ -7,7 +7,7 @@ - +